#include "logger.h"

#include <QDateTime>
#include <QTextStream>
#include <QDebug>

#include <stdio.h>

Logger::Logger()
{
//    printf("Logger Init\n");
}

Logger::~Logger()
{
    if(file) {
        delete file;
        file = nullptr;
    }

//    printf("Logger Deinit\n");
}

bool Logger::setLogFile(const QString &filePath)
{
    qDebug() << "set log file:" << filePath;
    auto &logger = Logger::instance();

    logger.mutex.lock();

    if(file) {
        delete file;
        file = nullptr;
    }

    file = new QFile(filePath);
    bool ret = file->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
    logger.mutex.unlock();
    if(! ret) {
        qWarning() << "Fail to open log file:" << filePath;
    }

    return ret;
}

void Logger::log(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    const char *fileName = context.file ? context.file : "";
    int line = context.line;
    auto timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");

    char levelChar;

    switch (type) {
    case QtDebugMsg:
        levelChar = 'D';
        break;
    case QtInfoMsg:
        levelChar = 'I';
        break;
    case QtWarningMsg:
        levelChar = 'W';
        break;
    case QtCriticalMsg:
        levelChar = 'C';
        break;
    case QtFatalMsg:
        levelChar = 'F';
        break;
    default:
        levelChar = 'U';
    }

    QString str;
    if(strcmp(context.category, "LIS") == 0) {
        str = QString("%2: %3\n").
              arg(timestamp, msg);
    } else {
        if(context.file) {
            str = QString("%1 %2: %3:%4: %6\n").
                  arg(levelChar).
                  arg(timestamp, fileName).
                  arg(line).
                  arg(msg);
        } else {
            str = QString("%1 %2: %3\n").
                  arg(levelChar).
                  arg(timestamp, msg);
        }
    }

    auto &logger = Logger::instance();
    if(logger.file && logger.file->isOpen()) {
        QTextStream fout(logger.file);

        logger.mutex.lock();
        fout << str;
        logger.mutex.unlock();
    } else {
        QTextStream cout(stdout,  QIODevice::WriteOnly);

        cout << str;
    }
}
